package cn.gogoyc.pet.service.impl;

import cn.gogoyc.order.domain.OrderPetAcquisition;
import cn.gogoyc.order.mapper.OrderPetAcquisitionMapper;
import cn.gogoyc.org.basic.dto.OrderDto;
import cn.gogoyc.org.basic.exception.BusinessException;
import cn.gogoyc.org.basic.servie.IBaiduAiAuditService;
import cn.gogoyc.org.basic.servie.impl.BaseServiceImpl;
import cn.gogoyc.org.basic.util.*;
import cn.gogoyc.org.domain.Employee;
import cn.gogoyc.org.domain.Shop;
import cn.gogoyc.org.mapper.EmployeeMapper;
import cn.gogoyc.org.mapper.ShopMapper;
import cn.gogoyc.pet.domain.SearchMasterMsg;
import cn.gogoyc.pet.domain.SearchMasterMsgAuditLog;
import cn.gogoyc.pet.mapper.SearchMasterMsgAuditLogMapper;
import cn.gogoyc.pet.mapper.SearchMasterMsgMapper;
import cn.gogoyc.pet.query.SearchMasterMsgQuery;
import cn.gogoyc.pet.service.ISearchMasterMsgService;
import cn.gogoyc.user.domain.Logininfo;
import cn.gogoyc.user.domain.User;
import cn.gogoyc.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * SearchMasterMsgServiceImpl业务实现类:
 */
@Service
public class SearchMasterMsgServiceImpl extends BaseServiceImpl<SearchMasterMsg> implements ISearchMasterMsgService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private IBaiduAiAuditService baiduAiAuditService;
    @Autowired
    private SearchMasterMsgMapper searchMasterMsgMapper;
    @Autowired
    private SearchMasterMsgAuditLogMapper searchMasterMsgAuditLogMapper;
    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private OrderPetAcquisitionMapper orderPetAcquisitionMapper;

    @Override
    @Transactional
    public AjaxResult publish(SearchMasterMsg msg, HttpServletRequest request) {
        //获取请求头里面的数据并用工具类转为对象
        Logininfo logininfo = LoginContext.getLogininfo(request);
        //根据logininfo对象的id去查user表的数据 找出当前登录人的信息
        User user = userMapper.loadByLogininfoId(logininfo.getId());
        //将用户和发布信息表关联起来
        msg.setUserId(user.getId());
        //关联后入库
        searchMasterMsgMapper.save(msg);

        /*这里不管用户是否合法合规先入库,根据API判断修改状态*/

        //审核标题名称和宠物名称
        Boolean boo1 = baiduAiAuditService.textAudit(msg.getName() + msg.getTitle());
        //审核图片---这里还没做图片
        Boolean boo2 = baiduAiAuditService.imageAudit(msg.getResources());
        if (boo1 && boo2) {
            //都合规则将状态改为1---待处理
            msg.setState(1);
            /*关联日志并记录*/
            SearchMasterMsgAuditLog log = new SearchMasterMsgAuditLog();
            log.setState(1);
            log.setMsgId(msg.getId());
            log.setNote("审核成功");
            //关联后日志入库
            searchMasterMsgAuditLogMapper.save(log);

            //根据用户的地址计算经纬度
            Point point = DistanceUtils.getPoint(msg.getAddress());
            //将经纬度给工具类和所有店铺的地址,计算是否有自定义范围内的店铺
            Shop nearestShop = DistanceUtils.getNearestShop(point, shopMapper.loadAll());
            if (nearestShop != null) {
                //如果有则将该发布信息和店铺关联起来,并短信提醒去接取宠物..
                msg.setShopId(nearestShop.getId());
                System.out.println("您有新的订单,请到" + msg.getAddress() + "接取宠物");
            } else {
                //如果没有自定义范围内的商铺则将状态改为3--放到宠物池待领取
                msg.setState(3);
                //短信提醒用户
                System.out.println("您附近没有商家,请等待商家后续入驻...");
                //前端弹窗提醒没有商家
                return AjaxResult.me().setSuccess(false).setMsg("您附近没有商家,请等待商家后续入驻...");
            }

            //这里审核成功则入库,先不管是否有店铺接纳,没接纳的宠物则放宠物池
            searchMasterMsgMapper.update(msg);
            return new AjaxResult();
        }else {
            //审核失败则先创建日志对象记录信息入库
            SearchMasterMsgAuditLog log = new SearchMasterMsgAuditLog();
            log.setMsgId(msg.getId());
            log.setState(0);
            log.setNote("审核失败");
            searchMasterMsgAuditLogMapper.save(log);
            //并短信提醒用户违规部分...
            System.out.println("发布寻主消息失败...请修改您图片或标题名字后重试...");

            //既然违规则删除状态为0的冗余数据
            searchMasterMsgMapper.remove(msg.getId());
            //返回前端提醒用户违规审核失败
            return AjaxResult.me().setSuccess(false).setMsg("发布寻主消息失败...请修改您图片或标题名字后重试...");
        }
    }

    /**
     * 动态SQL,只展示状态为3的宠物
     * @param query
     * @param request
     * @return
     */
    @Override
    public PageList<SearchMasterMsg> toSearchMasterPool(SearchMasterMsgQuery query, HttpServletRequest request) {
        //触发这个请求的将状态改为3 只展示领养池中的宠物
        query.setState(3);
        return super.queryPage(query);
    }

    /**
     * 动态SQL,只展示状态为2=寻主成功的宠物,超级管理员查询全部
     * @param query
     * @param request
     * @return
     */
    @Override
    public PageList<SearchMasterMsg> finish(SearchMasterMsgQuery query, HttpServletRequest request) {
        query.setState(2);
        Logininfo logininfo = LoginContext.getLogininfo(request);
        Employee employee = employeeMapper.loadByLogininfoId(logininfo.getId());
        if (employee.getShop_id()!=null){
            //只展示自己店铺寻主成功的宠物
            query.setShopId(employee.getShop_id());
        }
        return super.queryPage(query);
    }

    /**
     * 动态SQL,只展示待处理的宠物,超级管理员查询全部
     * @param query
     * @param request
     * @return
     */
    @Override
    public PageList<SearchMasterMsg> toHandle(SearchMasterMsgQuery query, HttpServletRequest request) {
        query.setState(1);
        Logininfo logininfo = LoginContext.getLogininfo(request);
        Employee employee = employeeMapper.loadByLogininfoId(logininfo.getId());
        if (employee.getShop_id()!=null){
            query.setShopId(employee.getShop_id());
        }
        return super.queryPage(query);
    }

    /**
     * 用户能查看到的宠物信息
     * @param query
     * @param request
     * @return
     */
    @Override
    public PageList<SearchMasterMsg> user(SearchMasterMsgQuery query, HttpServletRequest request) {
        Logininfo logininfo = LoginContext.getLogininfo(request);
        User user = userMapper.loadByLogininfoId(logininfo.getId());
        query.setUserId(user.getId());
        return super.queryPage(query);
    }

    /**
     * 拒单,状态改为3,shopId置空 放入领养池
     * @param id
     */
    @Override
    public void reject(Long id) {
        searchMasterMsgMapper.reject(id);
    }

    /**
     * 接单请求,提交时Dto对象接受前端参数进行生成订单
     * @param orderDto
     */
    @Override
    public void accept(OrderDto orderDto) {
        //先去查找提交的寻主宠物信息是否有订单
        OrderPetAcquisition order = orderPetAcquisitionMapper.loadBymsgId(orderDto.getMsgId());
        //如果不等于空并且状态是0(待处理)
        if (order!=null && order.getState()==0){
            //自定义异常提醒前端
            throw new BusinessException("该正在处理,请勿重复接取订单...");
        }

        //走到这下面说明订单不冲突 继续生成,根据提交的寻主信息查询到该对象的详细信息
        SearchMasterMsg msg = searchMasterMsgMapper.loadById(orderDto.getMsgId());
        //创建个新订单对象,将寻主信息和处理人信息交给订单对象进行处理赋值
        OrderPetAcquisition newOrder = createOrder(msg,orderDto);
        //创建好订单后入库
        orderPetAcquisitionMapper.save(newOrder);
        //短信提醒店员
        System.out.println("您的新的订单,请在两天之内到"+msg.getAddress()+"接取宠物");
    }

    /**
     * 根据已知的寻主信息和处理人信息进行创建订单
     * @param msg
     * @param orderDto
     * @return
     */
    private OrderPetAcquisition createOrder(SearchMasterMsg msg, OrderDto orderDto) {
        OrderPetAcquisition order = new OrderPetAcquisition();
        //工具类生成随机订单编号
        String orderSn = CodeGenerateUtils.generateOrderSn(msg.getUserId());
        order.setOrderSn(orderSn);
        //宠物接单时的备注信息
        order.setDigest(orderDto.getNote());
        //3天之后没有接单就自动取消 - 定时器
        order.setLastcomfirmtime(new Date(System.currentTimeMillis() + 3*24*60*60*1000));
        //宠物的价格
        order.setPrice(msg.getPrice());
        //支付类型 - 确认订单才设置
        //宠物id - 确认订单，接回宠物再设置
        //关联用户的信息,方便后续有事联系
        order.setUserId(msg.getUserId());
        //关联店铺的信息
        order.setShopId(msg.getShopId());
        //关联宠物的地址
        order.setAddress(msg.getAddress());
        //关联店铺处理人的信息
        order.setEmpId(orderDto.getHandler());
        //关联寻主信息
        order.setSearchMasterMsgId(orderDto.getMsgId());
        return order;
    }
}
